package com.spring.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Service;

import com.google.common.base.Strings;

import com.spring.authManage.dao.ResourceInfoDao;
import com.spring.authManage.pojo.ResourceInfo;


@Service
public class CustomInvocationSecurityMetadataSourceService implements
		FilterInvocationSecurityMetadataSource {
	private static Logger logger = Logger
			.getLogger(CustomInvocationSecurityMetadataSourceService.class);

	private ResourceInfoDao resourceInfoDao;

	public void setResourceInfoDao(ResourceInfoDao resourceInfoDao) {
		this.resourceInfoDao = resourceInfoDao;
	}
	private static Map<String, Collection<ConfigAttribute>> resourceMap;

	public CustomInvocationSecurityMetadataSourceService() {
		super();
	}

	public CustomInvocationSecurityMetadataSourceService(ResourceInfoDao resourceInfoDao) {
		this.resourceInfoDao = resourceInfoDao;
		loadResourceDefine();
	}

	// web启动时加载所有资源权限
	private void loadResourceDefine() {
		resourceMap = new LinkedHashMap<String, Collection<ConfigAttribute>>(); 
		List<ResourceInfo> resList = new ArrayList<ResourceInfo>();
		try {
			resList = resourceInfoDao.getAllEnabledResource();
		} catch (Exception e) {
			logger.error("加载资源权限异常!");
		}
		for (ResourceInfo res : resList) {
			String res_string = res.getUrl().toLowerCase();
			String roleName = res.getRoleName();
			if (Strings.isNullOrEmpty(roleName)){
				continue;
			}
			if (resourceMap.containsKey(res_string)) {
				SecurityConfig sc = new SecurityConfig(roleName);
				Collection<ConfigAttribute> collect = resourceMap.get(res_string);
				collect.add(sc);
			} else {
				Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
				SecurityConfig sc = new SecurityConfig(roleName);
				configAttributes.add(sc);
				resourceMap.put(res_string, configAttributes);
			}
		}
		return;
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

	/**
	 * 根据URL找到对应的权限配置
	 * 
	 * @param
	 * @return
	 * @throws Exception
	 */
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		String url = ((FilterInvocation) object).getRequestUrl().toLowerCase();
		int firstMark = url.indexOf("?");
		if (firstMark > -1) {
			url = url.substring(0, firstMark);
		}
		if (resourceMap == null) {
			loadResourceDefine();
		}
		return resourceMap.get(url);
	}

	@Override
	public boolean supports(Class<?> arg0) {
		return true;
	}
	/**
	 * 刷新内存
	 * @param
	 * @return
	 * @throws Exception
	 */
	public static void refresh(){
		resourceMap = null;
	}
}
